/***********************************************************************************************//**
*\n  @file       bus.cpp
*\n  @brief      Bus 总线基类
*\n  @details
*\n -----------------------------------------------------------------------------------
*\n  文件说明：
*\n		2. Bus 总线基类
*\n
*\n -----------------------------------------------------------------------------------
*\n  版本:	 修改人:       修改日期:        描述:
*\n  V0.01   罗先能        2021.4.9          创建
*\n
***************************************************************************************************/

/**************************************************************************************************
* 头文件
***************************************************************************************************/
#include <iostream>
#include "vme.h"
#include "bus.hpp"

#undef  DEBUG_LEVEL
#define DEBUG_LEVEL  2   // 定义debug级别 (0 ~ 5)
#include "vdebug.h"

using namespace std;

/**************************************************************************************************
* 宏定义、结构定义
***************************************************************************************************/


/**************************************************************************************************
* 全局变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有变量声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 私有函数声明、定义
***************************************************************************************************/


/**************************************************************************************************
* 全局函数声明、定义
***************************************************************************************************/
/// TBUS类（接口实现）
TBus::~TBus()
{
	if(NULL != this->pBaseAddress)
	{
		munmap(this->pBaseAddress, this->mAddressSize);
		this->pBaseAddress = NULL;
	}
	if (this->mFd > 0)
	{
		close(this->mFd);
		this->mFd = -1;
	}
	debug_printf("%s->~TBus() \n",this->mName);
}

TBus::TBus()
{
	/// this->mFd, mName, mLock, pBaseAddress
	memset(this->mName, 0, sizeof(this->mName));
	pthread_rwlock_init(&(this->mLock), NULL);
	this->mFd = -1;
	this->pBaseAddress = NULL;
	debug_printf("TBus::TBus() \n");
}

TBus::TBus(const char name[])
{

	memset(this->mName, 0, sizeof(this->mName));
	int iSize = sizeof(this->mName) - 1;
	iSize = iSize < strlen(name)  ? iSize : strlen(name);
	memcpy(this->mName, name, iSize);

	pthread_rwlock_init(&(this->mLock), NULL);
	this->mFd = -1;
	this->pBaseAddress = NULL;
	debug_printf("TBus::TBus(%s) \n",this->mName);
}


/*************************************************************************************//**
*\n 函数名称： TBus.TBus()
*\n 功能描述：
*\n            构造函数，将端口地址映射到进程空间
*\n 输入参数：
*\n            const char name[]     : 实例名称
*\n            long physicalAddress  : 端口物理基地址
*\n            long size             : 映射大小
*\n 输出参数:
*\n
*\n 返 回 值:
*\n
*\n -----------------------------------------------------------------------------------
*\n  版本:   修改人:       修改日期:        描述:
*\n  V0.01 罗先能        2021.4.15     创建
*****************************************************************************************/
TBus::TBus(const char name[], long physicalAddress, long size/*=0x1000*/)
{

	memset(this->mName, 0, sizeof(this->mName));
	int iSize = sizeof(this->mName) - 1;
	iSize = iSize < strlen(name)  ? iSize : strlen(name);
	memcpy(this->mName, name, iSize);

	pthread_rwlock_init(&(mLock), NULL);
	this->mFd = -1;
	this->pBaseAddress = NULL;

	mFd = open("/dev/mem",  O_RDWR | O_SYNC);
	if (mFd < 0)
	{
		debug_error("open(/dev/mem) < 0\n");
		return ;
	}
	this->mAddressSize = size;
	this->pBaseAddress = mmap(NULL, this->mAddressSize,
							  PROT_READ | PROT_WRITE, MAP_SHARED,
							  this->mFd, (off_t)physicalAddress);
	if (MAP_FAILED == this->pBaseAddress)
	{
		this->pBaseAddress = NULL;
		debug_error("mmap() < 0\n");
		return;
	}
	debug_printf("TBus::TBus(%s,0x%08lx,0x%08lx) \n",this->mName,physicalAddress,size);
}

int TBus::Init()
{
	return 0;
}

int TBus::Lock()
{
	int iRet = pthread_rwlock_wrlock(&mLock);
	return iRet;
}


int TBus::Unlock()
{
	int iRet = pthread_rwlock_unlock(&mLock);
	return iRet;
}


int TBus::Ioctl(long cmd, void *pBuf)
{
	if (mFd < 0)
	{
		debug_error("mFd < 0 \n");
		return -1;
	}

	int iRet = ioctl(mFd, cmd, pBuf);
	return iRet;
}


int TBus::Write(long offset, void *pBuf, long iCnt)
{
	if ((mFd < 0) || (NULL == pBuf) || (iCnt <= 0))
	{
		if (mFd < 0)
			debug_error("mFd < 0 \n");
		if (NULL == pBuf)
			debug_error("NULL == pBuf \n");
		if (iCnt <= 0)
			debug_error("iCnt <= 0 \n");
		return -1;
	}

	// 写寄存器
	RegisterSet(this->pBaseAddress, offset, *((long *)pBuf));
	return sizeof(long);
}


int TBus::Read(long offset, void *pBuf, long iCnt)
{
	if ((mFd < 0) || (NULL == pBuf) || (iCnt <= 0))
	{
		if (mFd < 0)
			debug_error("mFd < 0 \n");
		if (NULL == pBuf)
			debug_error("NULL == pBuf \n");
		if (iCnt <= 0)
			debug_error("iCnt <= 0 \n");
		return -1;
	}

	// 读寄存器
	*((long *)pBuf) = RegisterGet(this->pBaseAddress, offset);
	return sizeof(long);
}



